package hu.elte.inf.holiuml.model;

import hu.elte.inf.holiuml.gui.ConnectionEdgeOptionsDialog;
import hu.elte.inf.holiuml.gui.ObjectNodeOptionsDialog;
import hu.elte.inf.holiuml.gui.OptionsDialog;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuItem;

/**
 * @author Csaba Hoch
 */
public class CollaborationDiagram extends Diagram {

	private Vector<ObjectNode> objectNodes = new Vector<ObjectNode>();
	private Vector<ConnectionEdge> connectionEdges = new Vector<ConnectionEdge>();

	public CollaborationDiagram() {
	}

	@Override
	public void createMenu(JMenu menu) {
		menu.setText("Collaboration diagram");

		menu.add(new JMenuItem(new AbstractAction("New object node") {
			public void actionPerformed(ActionEvent e) {
				main.getCanvas().setDiagram(CollaborationDiagram.this);
				main.getCanvas().repaint();
				createNewObjectNode();
			}
		}));
		menu.add(new JMenuItem(new AbstractAction("New connection edge") {
			public void actionPerformed(ActionEvent e) {
				main.getCanvas().setDiagram(CollaborationDiagram.this);
				main.getCanvas().repaint();
				main.getCanvas().createNewEdge(EdgeType.CONNECTION);
			}
		}));

		super.createMenu(menu);
	}

	public void draw(Graphics g) {
		drawDrawables(g, connectionEdges);
		drawDrawables(g, commentEdges);
		drawDrawables(g, objectNodes);
		drawDrawables(g, commentNodes);
	}

	@Override
	public Node nodeUnderPoint(Point p) {
		Node node = null;
		node = nodeUnderPoint(commentNodes, p);
		if (node != null) {
			return node;
		}
		node = nodeUnderPoint(objectNodes, p);
		if (node != null) {
			return node;
		}
		return null;
	}

	@Override
	public Edge edgeUnderPoint(Point p) {
		Edge edge = null;
		edge = edgeUnderPoint(connectionEdges, p);
		if (edge != null) {
			return edge;
		}
		edge = edgeUnderPoint(commentEdges, p);
		if (edge != null) {
			return edge;
		}
		return null;
	}

	/**
	 * Creates a new object node.
	 */
	public void createNewObjectNode() {
		ObjectNodeOptionsDialog optDlg = new ObjectNodeOptionsDialog(super.main, null);
		if (optDlg.getButtonCode() == OptionsDialog.OK) {
			objectNodes.add(optDlg.createData());
			main.getCanvas().repaint();
		}
	}

	@Override
	public void createNewEdge(Node node1, Node node2, EdgeType edgeType) {
		if (edgeType == EdgeType.CONNECTION) {
			ObjectNode objectNode1 = (ObjectNode) node1;
			ObjectNode objectNode2 = (ObjectNode) node2;
			ConnectionEdgeOptionsDialog connDlg = new ConnectionEdgeOptionsDialog(super.main,
					objectNode1, objectNode2, objectNodes, null);
			if (connDlg.getButtonCode() == OptionsDialog.OK) {
				System.out.println("elott");
				getConnectionEdges().add(connDlg.createConnection());
				System.out.println("utan");
				main.getCanvas().repaint();
			}
		} else {
			super.createNewEdge(node1, node2, edgeType);
		}
	}

	public Vector<ObjectNode> getObjectNodes() {
		return objectNodes;
	}

	public void setObjectNodes(Vector<ObjectNode> objectNodes) {
		this.objectNodes = objectNodes;
	}

	public Vector<ConnectionEdge> getConnectionEdges() { 
		return connectionEdges; 
	}

	public void setConnectionEdges(Vector<ConnectionEdge> connectionEdges) {
		this.connectionEdges = connectionEdges;
	}
	
	public void removeObjectNode(ObjectNode objectNode){
		ConnectionEdge connectionEdge;
		while ((connectionEdge = searchConnectionEdgeByObjectNode(objectNode))!= null) {
			connectionEdges.remove(connectionEdge);
		}
		objectNodes.removeElement(objectNode);
		main.getCanvas().repaint();
	}
	
	public ConnectionEdge searchConnectionEdgeByObjectNode(ObjectNode objectNode){
		ConnectionEdge connectionEdge = null;
		int connectionEdgeIndex = 0;
		while (connectionEdgeIndex < connectionEdges.size() &&
				(ObjectNode)connectionEdges.elementAt(connectionEdgeIndex).getNodeBegin() != objectNode &&
				(ObjectNode)connectionEdges.elementAt(connectionEdgeIndex).getNodeEnd() != objectNode ) {
			connectionEdgeIndex++;
		}
		if (connectionEdgeIndex != connectionEdges.size()){
			connectionEdge = connectionEdges.elementAt(connectionEdgeIndex);
		}
		return connectionEdge;
	}
	
	/**
	 * Removes the first (lowest-indexed) occurrence of the argument from this vector.
	 * 
	 * @param  connectionEdge
	 */
	public void removeConnectionEdge(ConnectionEdge connectionEdge )
	{
		connectionEdges.removeElement(connectionEdge);
		main.getCanvas().repaint();
	}
    
	/**
	 * Deletes the component at the specified index.
	 * 
	 * @param index 
	 */
	public void removeConnectionEdgeAt(int index )
	{
		connectionEdges.removeElementAt(index);
	}
}
